#ifndef _VECTEUR_H
#define _VECTEUR_H

/** Fichier qui définit les classes représentant les vecteurs et vecteurs
 * unitaires de l'espace.
 *
 * Ce fichier contient la définition des classes Vecteur et VecteurU.
 *
 * @file Vecteur.hpp
 * @author Jean-Marc Comby + Romain Dequesne
 * @author Johan "Solo" Luisier
 *
 * @date 07 Avril 2004
 */

#include "Coord.hpp"

class VecteurU;

/** Classe implémentant les vecteurs de l'espace.
 *
 * Cette classe implémente les vecteurs de l'espace. Comme un vecteur a trois
 * coordonnées il hérite naturellement de Coord. Toutes les opérations avec deux
 * vecteurs, un vecteur et un scalaire sont implémentées ici.
 *
 * @author Jean-Marc Comby + Romain Dequesne
 * @author Johan "Solo" Luisier
 *
 * @date 24 Juin 2011
 *
 * @class Vecteur "Vecteur.hpp" "Algebre/Vecteur.hpp"
 */
class Vecteur : public Coord
{
public:
    // Constructeur
    Vecteur( const double& x = 0., const double& y = 0., const double& z = 0. );
    Vecteur( const Coord&, const Coord& );
    Vecteur( const Coord& );
    Vecteur( const Vecteur& );
    Vecteur( const VecteurU& );
    Vecteur( const VecteurBase& vecBoost );
    // Destructeur
    virtual ~Vecteur();

    Vecteur &operator=( const VecteurBase& vecBoost );

    // Addition et soustraction de vecteurs
    Vecteur& operator+=( const Vecteur& );
    Vecteur operator+( Vecteur const& ) const;
    Vecteur& operator-=( Vecteur const& );
    Vecteur operator-( Vecteur const& ) const;

    // Multiplication
    Vecteur& operator*=( const double& );
    Vecteur operator*( const double& ) const;
    friend Vecteur operator*( const double&, Vecteur const & );

    // Produit scalaire
    double operator*( const Vecteur& ) const;
    double operator*( const Coord& pt ) const;
    /**
     * Permet d'obtenir le produit scalaire d'un vecteur par un point.
     *
     * Fait appel à la fonction inner_prod.
     *
     * @param[in] pt point de l'espace.
     * @param[in] vec vecteur de l'espace.
     *
     * @return la valeur du produit scalaire \f$ \vec{OP} \cdot \vec{v}
     * \f$.
     */
    friend double operator*( const Coord& pt, const Vecteur& vec );

    // Produit vectoriel
    Vecteur operator^( const Vecteur& ) const;

    // Oppose d un vecteur
    Vecteur operator-() const;

    // Angle entre deux vecteurs
    double angle( const Vecteur & ) const;

    // Norme d'un vecteur, attention retourne la valeur au carre
    double norme() const;

    // Projection orthogonale d un vecteur unitaire
    Vecteur project( const VecteurU& ) const;

    // le perpendiculaire de la pojection orthogonale
    Vecteur OrthoProject( const VecteurU& ) const;

    // calcule du symetrique du vecteur par rapport a un axe
    Vecteur reflect( const VecteurU& axe ) const;
};

/** Classe implémentant les vecteurs unitaires de l'espace.
 *
 * Cette classe implémente les vecteurs unitaires de l'espace. C'est une version
 * spécialisée de Vecteur, dont on force ici la norme à 1.
 *
 * @author Jean-Marc Comby + Romain Dequesne
 * @author Johan "Solo" Luisier
 *
 * @date 7 Avril 2004
 *
 * @class VecteurU "Vecteur.hpp" "Algebre/Vecteur.hpp"
 */
class VecteurU : public Vecteur
{
public:
    VecteurU();
    VecteurU( const double& x, const double& y, const double& z );
    VecteurU( const Vecteur&) ;
    VecteurU( const Coord& a, const Coord& b );
    VecteurU( const VecteurBase& vecBoost );
    virtual ~VecteurU();

    VecteurU &operator=( const VecteurBase& vecBoost );

    void transforme();
};
#endif
